package com.zq.assistant.utils;

import android.os.Handler;
import android.os.Looper;

import com.squareup.okhttp.Callback;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import com.zq.assistant.bean.ResultBase;
import com.zq.assistant.func.apifactory.callback.FailureCallback;
import com.zq.assistant.func.apifactory.callback.ResultCallback;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketException;
import java.net.SocketTimeoutException;

/**数据接口回调
 * Created by zhangqiang on 2016/5/18.
 */
public class ObjectCallback implements Callback {

    private static final Handler handler = new Handler(Looper.getMainLooper());

    private Class<?> clazz;
    private Class<?> geneticClass;
    private ResultCallback callback;

    public ObjectCallback(Class<?> clazz) {
        this(clazz,null,null);
    }

    public ObjectCallback(Class<?> clazz, Class<?> geneticClass) {
       this(clazz,geneticClass,null);
    }

    public ObjectCallback(Class<?> clazz, ResultCallback callback) {
        this.clazz = clazz;
        this.callback = callback;
    }

    public ObjectCallback(Class<?> clazz, Class<?> geneticClass, ResultCallback callback) {
        this.clazz = clazz;
        this.geneticClass = geneticClass;
        this.callback = callback;
    }

    @Override
    public void onFailure(Request request, final IOException e) {

        if(e != null && "Canceled".equals(e.getMessage())){

            //不处理
        }else if(e instanceof SocketTimeoutException || (e instanceof InterruptedIOException && "timeout".equals(e.getMessage()))){

            invokeError(FailureCallback.CONNECT_TIME_OUT,"connect time out");
        }else if(e instanceof SocketException){

            //不处理
            invokeError(FailureCallback.RESPONSE_ERROR,e.getMessage());
        }else{

            invokeError(FailureCallback.RESPONSE_ERROR,"response error");
        }
        if(e != null){
            e.printStackTrace();
        }
    }

    @Override
    public void onResponse(Response response) throws IOException {

        if(callback == null){
            return;
        }

        if(!response.isSuccessful()) {

            invokeError(FailureCallback.RESPONSE_ERROR,"response error : " + response.message());
            return;
        }


        ResponseBody responseBody = response.body();
        if(responseBody == null){

            invokeError(FailureCallback.RESPONSE_ERROR,"response error");
            return;
        }

        String jsonString = responseBody.string();
        Object object = JsonUtils.toObject(jsonString,clazz,geneticClass);

        if(object == null){
            invokeError(FailureCallback.JSON_FORMAT_ERROR,"json convert error from json : " + jsonString);
            return;
        }

        invokeSuccess(object);
    }


    private static void runOnUIThread(Runnable runnable){

        if(Looper.myLooper() == Looper.getMainLooper()){
            runnable.run();
        }else{
            handler.post(runnable);
        }
    }


    private void invokeError(final int errorCode, final String message){

        if(callback == null){
            return;
        }

        runOnUIThread(new Runnable() {
            @Override
            public void run() {
                callback.onFail(errorCode, message);
            }
        });
    }

    private void invokeSuccess(final Object object){

        if(callback == null){
            return;
        }

        runOnUIThread(new Runnable() {
            @Override
            public void run() {

                callback.onSuccess((ResultBase) object);
            }
        });
    }

}
